/**
 * COPYRIGHT© KMTC 2007
 * This software is the proprietary information of Korea Marine Transport Co.LTD
 * 
 * Revision History
 * Author					Date				Description
 * ------					----				-----------
 * 김주희@wees.co.kr	2007.12.14		기본으로 사용되는 RuntimeException 클래스	
 */
package kr.or.javacafe.common.exception;

import java.io.PrintStream;
import java.io.*;

/**
 * @author mousing
 *
 */
public class KmtcRuntimeException extends RuntimeException {
	
	private static final long serialVersionUID = -5018154911981821301L;
	
	private Throwable cause;
	
	public KmtcRuntimeException(String msg) {
        super(msg);
    }
	
	public KmtcRuntimeException( Throwable cause ) {
        super(cause);
    }
	
	public KmtcRuntimeException(String msg, Throwable cause) {
        super(msg);
        this.cause = cause;
    }
	
	public Throwable getCause() {
        // Even if you cannot set the cause of this exception other than through
        // the constructor, we check for the cause being "this" here, as the cause
        // could still be set to "this" via reflection: for example, by a remoting
        // deserializer like Hessian's.
        return (this.cause == this ? null : this.cause);
    }
	
	public String getMessage() {
        return buildMessage(super.getMessage(), getCause());
    }
	
	public void printStackTrace(PrintStream ps){
		if( getCause() == null ){
			super.printStackTrace(ps);
		}else{
			 ps.println(this);
	         ps.print("Caused by: ");
	         getCause().printStackTrace(ps);
		}
	}
	
	public void printStackTrace(PrintWriter pw) {
        if (getCause() == null) {
            super.printStackTrace(pw);
        }
        else {
            pw.println(this);
            pw.print("Caused by: ");
            getCause().printStackTrace(pw);
        }
    }
	
	public Throwable getRootCause() {
        Throwable cause = getCause();
        if (cause instanceof KmtcRuntimeException) {
            return ((KmtcRuntimeException) cause).getRootCause();
        }
        else {
            return cause;
        }
    }
	
	public boolean contains(Class exClass) {
        if (exClass == null) {
            return false;
        }
        if (exClass.isInstance(this)) {
            return true;
        }
        Throwable cause = getCause();
        if (cause instanceof KmtcRuntimeException) {
            return ((KmtcRuntimeException) cause).contains(exClass);
        }
        else {
            return (cause != null && exClass.isInstance(cause));
        }
    }
	
	public static String buildMessage(String message, Throwable cause){
		if( cause != null ){
			StringBuffer buff = new StringBuffer();
			if( message != null ){
				buff.append(message).append("; ");
			}
			buff.append("nested exception is ").append(cause);
			
			return buff.toString();
		}else{
			return message;
			//return message.replaceAll("\n", "<br>");
		}
	}
	
}
